package systemInformation;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Vector;

import org.snmp4j.PDU;
import org.snmp4j.agent.mo.snmp.DateAndTime;
import org.snmp4j.agent.mo.snmp.DisplayString;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;

import features.SNMPException;
import features.SNMPSession;
import features.SNMPValue;

public class InstalledSwInfo {
	private final static String INDEX_OID = ".1.3.6.1.2.1.25.6.3.1.1";
	
	private final static String NAME_OID = ".1.3.6.1.2.1.25.6.3.1.2";
	
	private final static String TYPE_OID = ".1.3.6.1.2.1.25.6.3.1.4";
	
	private final static String DATE_OID = ".1.3.6.1.2.1.25.6.3.1.5";
	
	private int index;

	private String name;

	private String type;

	private String date;
	
	@SuppressWarnings("unchecked")
	public static InstalledSwInfo fromPDU(PDU pdu) {
		InstalledSwInfo info = new InstalledSwInfo();
		Vector<VariableBinding> variableBindings = pdu.getVariableBindings();
		
		for (VariableBinding variableBinding : variableBindings) {
			if(variableBinding.getOid().compareTo(new OID(INDEX_OID)) == 0) {
				info.setIndex(((Integer32) variableBinding.getVariable()).getValue());
			} else if(variableBinding.getOid().compareTo(new OID(NAME_OID)) == 0) {
				info.setName(((DisplayString) variableBinding.getVariable()).toString());
			} else if(variableBinding.getOid().compareTo(new OID(TYPE_OID)) == 0) {
				info.setType(ProcessType.fromVariable((Integer32) variableBinding.getVariable()).toString());
			} else if(variableBinding.getOid().compareTo(new OID(DATE_OID)) == 0) {
				info.setDate(((DateAndTime) variableBinding.getVariable()).toString());
			}
		}
		
		return info;
	}
	
	public static List<InstalledSwInfo> fromSession(SNMPSession session) throws SNMPException {
		List<InstalledSwInfo> installedSws = new ArrayList<InstalledSwInfo>();
		List<SNMPValue> lstIndex = session.getColumn(INDEX_OID);
		List<SNMPValue> lstName = session.getColumn(NAME_OID);
		List<SNMPValue> lstType = session.getColumn(TYPE_OID);
		List<SNMPValue> lstDate = session.getColumn(DATE_OID);
		
		Calendar c = Calendar.getInstance();
		
		for (int i = 0; i < lstIndex.size(); i++) {
			InstalledSwInfo info = new InstalledSwInfo();
			
			info.setIndex(lstIndex.get(i).toInt());
			info.setName(lstName.get(i).toString());
			info.setType(ProcessType.fromInt(lstType.get(i).toInt()).toString());
			
			c.setTimeInMillis(lstDate.get(i).toLong());
			
			info.setDate(c.getTime().toString());
			
			installedSws.add(info);
		}
		
		return installedSws;
	}

	@Override
	public String toString() {
		return "InstalledSwInfo [" + index + ", " + name + ", " + date + ", " + type + "]";
	}

	public String getDate() {
		return this.date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public int getIndex() {
		return this.index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getType() {
		return this.type;
	}

	public void setType(String status) {
		this.type = status;
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((this.date == null) ? 0 : this.date.hashCode());
		result = PRIME * result + this.index;
		result = PRIME * result + ((this.name == null) ? 0 : this.name.hashCode());
		result = PRIME * result + ((this.type == null) ? 0 : this.type.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final InstalledSwInfo other = (InstalledSwInfo) obj;
		if (this.date == null) {
			if (other.date != null)
				return false;
		} else if (!this.date.equals(other.date))
			return false;
		if (this.index != other.index)
			return false;
		if (this.name == null) {
			if (other.name != null)
				return false;
		} else if (!this.name.equals(other.name))
			return false;
		if (this.type == null) {
			if (other.type != null)
				return false;
		} else if (!this.type.equals(other.type))
			return false;
		return true;
	}
}
